//
// Copyright (c) 2005 BroadVision, Inc. All rights reserved.
//
// This software is copyrighted.  Under the copyright laws, this software
// may not be copied, in whole or in part, without prior written consent
// of BroadVision, Inc. or its assignees.  This software is provided under
// the terms of a license between BroadVision and the recipient, and its
// use is subject to the terms of that license.
//
// This software may be protected by one or more U.S. and International
// patents.  Certain applications of BroadVision One-To-One software are
// covered by U.S. patent 5,710,887.
//
// TRADEMARKS: BroadVision and BroadVision One-To-One are registered
// trademarks of BroadVision, Inc., in the United States and the European
// Community, and are trademarks of BroadVision, Inc., in other
// countries.  The BroadVision logo, is a trademark of BroadVision, Inc.,
// in the United States and other countries. Additionally, IONA and Orbix
// are trademarks of IONA Technologies, Ltd.  RSA, MD5, and RC2 are
// trademarks of RSA Data Security, Inc.
//

package com.broadvision.manage.common.tools.action.user;


import java.util.*;
import java.security.Principal;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.Globals;

import com.broadvision.web.util.ViewDynaBean;
import com.broadvision.system.accesscontrol.client.*;
import com.broadvision.visitor.client.VisitorManager;
import com.broadvision.visitor.client.Visitor;
import com.broadvision.lictool2.LicToolWebApp;
import com.broadvision.manage.tools.action.BaseAction;
import com.broadvision.system.accesscontrol.utils.ServiceRoleFilter;
import com.broadvision.manage.common.tools.user.UserProfile;

import com.broadvision.visitor.client.VisitorGroupManager;
import com.broadvision.visitor.interfaces.VisitorGroup;
import com.broadvision.portal.services.*;

/**
 * Retrieves user's roles
 */
public class RoleViewAction extends BaseAction {

  public static final String VIEW_BEAN_NAME = "mtUserRoleView";
  public static final String DTO_BEAN_NAME  = "mtUserRoleDTO";
  public static final int  MAX_NUMBER_OF_GROUPS = 2147483646;

  public static final VisitorManager visitorMgr = new VisitorManager();

  /**
   * Implements the action for viewing user's roles.
   * <p> <p>
   * @param mapping <code>ActionMapping</code> object used to select this instance
   * @param form Optional <code>ActionForm</code> bean for this request (if any)
   * @param request <code>HttpServletRequest</code> object to process
   * @param response <code>HttpServletResponse</code> object to process
   * <p> <p>
   * @return <code>ActionForward</code> instance describing where and how
   * control should be forwarded, or null if the response has already been completed
   * <p> <p>
   * @throws Exception if an error occurs
   */
  public ActionForward processExecute(ActionMapping mapping,
                                      ActionForm form,
                                      HttpServletRequest request,
                                      HttpServletResponse response)
                               throws Exception
  {
    try {
      
	  // validate the user's role
	  PortalVisitor agent = getPortalVisitor(request);
      Visitor visitor = agent.getVisitor();
      
	  // Validate the user to authorize for this operation
	  long userId = ((Long) UserUtils.getP(form, "userId")).longValue();
      
	  boolean hasUserAdminRole = isUserInRole(visitor, UserProfile.USER_ADMIN);
	  boolean hasOrganizationAdminRole = UserProfile.isOrganizationAdmin(visitor);
      if( !hasUserAdminRole && !hasOrganizationAdminRole && userId != visitor.getId() ){
	    request.setAttribute(Globals.ERROR_KEY, "error.group.noGroupAdmin");
		return mapping.findForward("failure");
      }
	  if (hasUserAdminRole == false && userId != visitor.getId()) {
	  HashMap orgAdminsMap = new HashMap();
     
        AccessManager accessMgr = AccessManager.instance();
        List orgAdmins = accessMgr.getOwnerObjectsForPrincipal((Principal)visitor, UserProfile.ORGANIZATION_ADMIN);
        if (null != orgAdmins) {
          for (int j = 0; j < orgAdmins.size(); j++) {
            ACObjectID ac = (ACObjectID) orgAdmins.get(j);
            orgAdminsMap.put(ac.getObjectID().trim(), ac);
          }
        }
      
	  VisitorGroup[] groups = VisitorGroupManager.findAllGroupsVisitorBelongsTo(userId, MAX_NUMBER_OF_GROUPS);
      boolean doFQN = false;
	  if (null != groups) {
        for (int i = 0; i < groups.length; i++) {
		  if(doFQN == true)
            break;
          VisitorGroup group = groups[i];
          List parents = new ArrayList(1);
          parents.add(group);
          parents.addAll(group.getParents(true));
          for (int j = 0; parents != null && j < parents.size(); j++) {
            VisitorGroup parent = (VisitorGroup)parents.get(j);
            if (orgAdminsMap.containsKey(parent.getFullyQualifiedName())) {
              doFQN = true;
              break;
            }
          }
        }
      }
	  // visitor is not userAdmin, user is not equal to visitor id, visitor doesn't
	  // have any member under his/her organization group
	  if (!doFQN) {
		request.setAttribute(Globals.ERROR_KEY, "error.group.noGroupAdmin");
		return mapping.findForward("failure");
      }
	  }

	  ViewDynaBean view = new ViewDynaBean(VIEW_BEAN_NAME, mapping);
      request.setAttribute(VIEW_BEAN_NAME, view);
      //long userId = ((Long) UserUtils.getP(form, "userId")).longValue();
      Visitor user = visitorMgr.getVisitor(userId);
      GenericRoleDB genericRoleDB = new GenericRoleDB();
      GenericSectionDB genericSectionDB = new GenericSectionDB();
      List allGrantedRoles = genericRoleDB.getGrantedRolesForPrincipal((Principal)user, "/Global");
      int portalInstalled = LicToolWebApp.getInstance().checkTag("portal.framework");
      if (portalInstalled >= 0) {
        allGrantedRoles.addAll(genericRoleDB.getGrantedRolesForPrincipal((Principal)user, "/Global/Portal"));
      }
      if (portalInstalled >= 0) {
        allGrantedRoles.addAll(genericRoleDB.getGrantedRolesForPrincipal((Principal)user, "/Global/Personalization"));
      }
      allGrantedRoles.addAll(genericRoleDB.getGrantedRolesForPrincipal((Principal)user, "/Global/ContentManagement"));
      allGrantedRoles.addAll(genericRoleDB.getGrantedRolesForPrincipal((Principal)user, "/Global/ProcessManagementCenter"));
      int isStagingServices =  LicToolWebApp.getInstance().checkTag("staging.services");
      boolean hasStagingServices = genericSectionDB.sectionExists("StagingServices",
          genericSectionDB.getSection("/Global").getOid());
      if (isStagingServices >= 0 && hasStagingServices == true) {
        allGrantedRoles.addAll(genericRoleDB.getGrantedRolesForPrincipal((Principal)user, "/Global/StagingServices"));
      }
      
      int isCommerce =  LicToolWebApp.getInstance().checkTag("commerce.shopping");
      boolean hasCommerce = genericSectionDB.sectionExists("Commerce",
          genericSectionDB.getSection("/Global").getOid());
      if (isCommerce >= 0 && hasCommerce == true) {
        allGrantedRoles.addAll(genericRoleDB.getGrantedRolesForPrincipal((Principal)user, "/Global/Commerce"));
      }

      AccessManager accessMgr = AccessManager.instance();
      ServiceObjectInfo sOI = new ServiceObjectInfo(getServiceId(request));

      TreeMap tm = new TreeMap();
      for (Iterator it = allGrantedRoles.iterator(); it.hasNext(); ) {
        Object object = it.next();
        if (object instanceof UserRole) {
          UserRole userRole = (UserRole) object;

          /* validate service specific role */
          if (ServiceRoleFilter.isServiceRole(userRole)) {
             if (!ServiceRoleFilter.isUserPermittedServiceRole(user, userRole, sOI)) {
                continue;
             }
          }

          ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
          UserUtils.setP(oneDto, "name", userRole.getFriendlyName());
          UserUtils.setP(oneDto, "description", userRole.getDescription());
          tm.put(userRole.getFriendlyName(), oneDto);
          
        }
      }

      if (accessMgr.isUserInRole(user, "MicrositeCreator", sOI)) {
        UserRole userRole = genericRoleDB.getUserRole("MicrositeCreator");
        ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
        UserUtils.setP(oneDto, "name", userRole.getFriendlyName());
        UserUtils.setP(oneDto, "description", userRole.getDescription());
        tm.put(userRole.getFriendlyName(), oneDto);
      }
      List dtos = new ArrayList(tm.values());
      UserUtils.setP(view, "roleList", dtos);
      String formattedName = UserUtils.getFormattedName(user, 
          getResources(request), getLocale(request));
      UserUtils.setP(view, "formattedName", formattedName);
    }
    catch (Exception ex) {
      ex.printStackTrace();
      request.setAttribute(Globals.ERROR_KEY, "error.application");
      return mapping.findForward("failure");
    }
    return mapping.findForward("success");
  }
}
